import React, { useEffect, useRef } from "react";
import type { FC } from "react";

interface Particle {
  x: number;
  y: number;
  vx: number;
  vy: number;
  age: number;
}

class Particle {
  x: number;
  y: number;
  vx: number;
  vy: number;
  age: number;

  constructor() {
    this.x = 0;
    this.y = 0;
    this.vx = 0;
    this.vy = 0;
    this.age = 0;
    this.init();
  }

  init() {
    this.x = (Math.random() * window.innerWidth) | 0;
    this.y = (Math.random() * window.innerHeight) | 0;
    this.vx = Math.random() - 0.5;
    this.vy = Math.random() - 0.5;
    this.age = (Math.random() * 50) | 0;
  }

  update(mouse: { x: number; y: number }) {
    this.x += this.vx;
    this.y += this.vy;
    if (
      this.x < 0 ||
      this.x > window.innerWidth ||
      this.y < 0 ||
      this.y > window.innerHeight
    ) {
      this.init();
    }
    this.age--;
    if (this.age < 0) {
      this.age = (Math.random() * 50) | 0;
      this.vx += (Math.random() - 0.5) * 0.1;
      this.vy += (Math.random() - 0.5) * 0.1;
    }
    const r = Math.sqrt(
      Math.pow(this.x - mouse.x, 2) + Math.pow(this.y - mouse.y, 2)
    );
    if (r < 200) {
      this.x -= (this.x - mouse.x) / 500;
      this.y -= (this.y - mouse.y) / 500;
    }
  }

  draw(ctx: CanvasRenderingContext2D) {
    ctx.beginPath();
    ctx.arc(this.x, this.y, 1, 0, Math.PI * 2);
    ctx.fill();
  }
}

const ParticlesGravity: FC = () => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const particles: Particle[] = [];
  const mouse = { x: -500, y: -500 };

  useEffect(() => {
    if (!canvasRef.current) return;

    const canvas = canvasRef.current;
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    const ctx = canvas.getContext("2d");

    if (!ctx) return;

    const init = () => {
      for (let i = 0; i < 200; i++) {
        particles.push(new Particle());
      }
    };

    init();

    // const handleMouseMove = (evt: MouseEvent) => {
    //   mouse.x = evt.x;
    //   mouse.y = evt.y;
    // };

    // document.addEventListener("mousemove", handleMouseMove);

    const ani = () => {
      ctx.globalAlpha = 0.1;
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      for (const i in particles) {
        const p = particles[i];
        p.update(mouse);
        p.draw(ctx);
        for (let j = 0; j < particles.length; j++) {
          const p2 = particles[j];
          const r = Math.sqrt(
            Math.pow(p.x - p2.x, 2) + Math.pow(p.y - p2.y, 2)
          );
          if (r < 50) {
            ctx.beginPath();
            ctx.moveTo(p.x, p.y);
            ctx.lineTo(p2.x, p2.y);
            ctx.strokeStyle = "rgba(0,0,0," + (1 - r / 50) + ")";
            ctx.stroke();
          }
        }
      }
      requestAnimationFrame(ani);
    };

    ani();

    return () => {
      //   document.removeEventListener("mousemove", handleMouseMove);
    };
  }, []);

  return <canvas ref={canvasRef} id="particles-gravity-canvas" />;
};

export default ParticlesGravity;
